<?php
/**
 * 常用正则验证类
 * User: dxk
 * Date: 2020/07/17
 */

namespace App\Library\Service;
class Verify
{
    /**
     * 过滤字符串，只保留 汉字、字母、数字
     * @param $str
     * @return string
     */
    public static function filterStr($str): string
    {
        preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9]/u', $str, $result);
        return implode('', $result[0]);
    }

    /**
     * 过滤表情符号
     * @param $str
     * @return string
     */
    public static function filterEmoji($str): string
    {
        preg_match_all('/[\x{4e00}-\x{9fa5}a-zA-Z0-9[:punct:]]/u', $str, $result);
        return implode('', $result[0]);
    }

    /**
     * 判断是否包含表情符号
     * @param $str
     * @return bool
     */
    public static function isIncludeEmoji($str): bool
    {
        return !(self::filterEmoji($str) == $str);
    }

    /**
     * 验证字符串
     * @param $string
     * @return bool
     */
    public static function isString($string)
    {
        return is_string($string);
    }

    /**
     * 是否为大于0的数字
     * @param $string
     * @return bool
     */
    public static function isGtZero($string)
    {
        if (!is_numeric($string) || $string <= 0) return false;
        return true;
    }

    /**
     * 验证数字字符串
     * @param $string
     * @return bool
     */
    public static function isNumeric($string)
    {
        return is_numeric($string);
    }

    /**
     * 验证整数
     * @param $string
     * @return bool
     */
    public static function isInt($string)
    {
        return is_numeric($string) && (int)$string == $string;
    }

    /**
     * 验证为空
     * @param $string
     * @return bool
     */
    public static function isEmpty($string)
    {
        return empty($string);
    }

    /**
     * 验证不为空
     * @param $string
     * @return bool
     */
    public static function notEmpty($string)
    {
        return !empty($string);
    }

    /**
     * 验证用户名
     * 字母、数字、下划线、汉字组成,2-20位字符,不能为纯数字
     *
     * @param $user_name
     * @param int $min_len
     * @param int $max_len
     * @return bool|int
     */
    public static function isUserName($user_name, $min_len = 2, $max_len = 20)
    {
        if (empty($user_name)) {
            return false;
        }
        //需求修改 2-20位，数字字母
        $match = '/^([a-zA-Z0-9]){' . $min_len . ',' . $max_len . '}$/';
        return preg_match($match, $user_name);
        $match = '/^(?![0-9]+$)[\w\x{4e00}-\x{9fa5}]{' . $min_len . ',' . $max_len . '}$/iu';
        return preg_match($match, $user_name);
    }

    /**
     * 验证昵称
     * 字符限制在30字节，不可输入特殊符号，只能包含中英文、横线、下划线
     *
     * @param $nickname
     * @param int $min_len
     * @param int $max_len
     * @return bool|int
     */
    public static function isNickname($nickname, $min_len = 2, $max_len = 30)
    {
        if (empty($nickname)) {
            return false;
        }
        ///^[\x{4e00}-\x{9fa5}A-Za-z0-9\-_]
        $match = '/^[\x{4e00}-\x{9fa5}A-Za-z\-_]{' . $min_len . ',' . $max_len . '}$/u';
        return preg_match($match, $nickname);
    }

    /**
     * 验证用户名
     * @param $name
     * @param int $min_len
     * @param int $max_len
     * @param string $charset
     * @return bool|int
     */
    public static function isName($name, $min_len = 2, $max_len = 20, $charset = 'ALL')
    {
        if (empty($name)) {
            return false;
        }
        switch ($charset) {
            case 'EN':
                $match = '/^[_\w\d]{' . $min_len . ',' . $max_len . '}$/iu';
                break;
            case 'CN':
                $match = '/^[_\x{4e00}-\x{9fa5}\d]{' . $min_len . ',' . $max_len . '}$/iu';
                break;
            default:
                $match = '/^[_\w\d\x{4e00}-\x{9fa5}]{' . $min_len . ',' . $max_len . '}$/iu';
        }
        return preg_match($match, $name);
    }

    public static $password_tip = "密码为6-20位,字母/数字/标点符号至少两种";

    /**
     * 验证密码格式
     * @param $password
     * @return bool|int
     */
    public static function isPassword($password)
    {
        $password = trim($password);
        if (empty($password)) {
            return '空密码';
        }
        if (!preg_match('/^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)]|[\(\)])+$)([^(0-9a-zA-Z)]|[\(\)]|[a-z]|[A-Z]|[0-9]){6,20}$/', $password)) {
            return '密码为6-20位,字母/数字/标点符号至少两种';
        }
        if (strpos($password, '123456') !== false || strpos($password, '654321') !== false) {
            return '密码过于简单，包含了连续的数字';
        }
        $pass_arr = str_split($password, 1);
        if (count(array_unique($pass_arr)) <= 2) {
            return '密码过于简单，包含了太多重复字符';
        }
        return true;
    }

    /**
     * 验证eamil格式
     * @param $email
     * @param string $match
     * @return bool|int
     */
    public static function isEmail($email, $match = '/^[\w\d]+[\w\d\-.]*@[\w\d\-.]+\.[\w\d]{2,10}$/i')
    {
        $email = trim($email);
        if (empty($email)) {
            return false;
        }
        return preg_match($match, $email);
    }

    /**
     * 验证电话号码
     * @param $telephone
     * @param string $match
     * @return bool|int
     */
    public static function isTelephone($telephone, $match = '/^0[0-9]{2,3}[-]?\d{7,8}$/')
    {
        $telephone = trim($telephone);
        if (empty($telephone)) {
            return false;
        }
        return preg_match($match, $telephone);
    }

    /**
     * 验证手机号
     * 1、由11位数字组成
     * 2、必须以数字1开头
     * 3、后续的10位数字可以是0-9之间的数字
     * @param $mobile
     * @return bool
     */
    public static function isMobile($mobile)
    {
        $mobile = trim($mobile);
        //必须以数字1开头
        if (!str_starts_with($mobile, '1')) {
            return false;
        }
        if (!preg_match('/\d{11}/', $mobile)) {
            return false;
        }
        return true;
    }

    /**
     * 验证邮政编码
     * @param $postcode
     * @param string $match
     * @return bool|int
     */
    public static function isPostcode($postcode, $match = '/\d{6}/')
    {
        $postcode = trim($postcode);
        if (empty($postcode)) {
            return false;
        }
        return preg_match($match, $postcode);
    }

    /**
     * 验证IP
     * @param $ip
     * @param string $match
     * @return bool|int
     */
    public static function isIp($ip, $match = '/^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$/')
    {
        $ip = trim($ip);
        if (empty($ip)) {
            return false;
        }
        return preg_match($match, $ip);
    }

    /**
     * 验证身份证号码
     * @param $idcard
     * @param string $match
     * @return bool|int
     */
    public static function isIdcard($idcard, $match = '/^\d{6}((1[89])|(2\d))\d{2}((0\d)|(1[0-2]))((3[01])|([0-2]\d))\d{3}(\d|X)$/i')
    {
        $idcard = trim($idcard);
        if (empty($idcard)) {
            return false;
        } else if (strlen($idcard) > 18) {
            return false;
        }
        return preg_match($match, $idcard);
    }

    /**
     * 验证域名
     * @param $domain
     * @param string $match
     * @return bool|int
     */
    public static function isDomain($domain, $match = '/^[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?$/')
    {
        $domain = strtolower(trim($domain));
        if (empty($domain)) {
            return false;
        }
        return preg_match($match, $domain);
    }

    /**
     * 验证URL
     * @param $url
     * @param string $match
     * @return bool|int
     */
    public static function isUrl($url, $match = '/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(:\d+)?(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?/')
    {
        $url = strtolower(trim($url));
        if (empty($url)) {
            return false;
        }
        return preg_match($match, $url);
    }

    /**
     * 验证物流单号
     * @param $logistics_number
     * @param string $match
     * @return bool|int
     */
    public static function isLogisticsNumber($logistics_number, $match = '/^[0-9a-zA-Z]+$/')
    {
        if (empty($logistics_number)) {
            return false;
        }
        $logistics_number = trim($logistics_number);
        return preg_match($match, $logistics_number);
    }

    /**
     * 验证DateTime
     * @param $date_time
     * @param string $match
     * @return bool|int
     */
    public static function isDateTime($date_time, $match = '/^d{4}-d{2}-d{2} d{2}:d{2}:d{2}$/s')
    {
        if (empty($date_time)) {
            return false;
        }
        $date_time = trim($date_time);
        return preg_match($match, $date_time);
    }

    /**
     * 验证qq
     * 5-11位数字
     *
     * @param $qq
     * @param int $min_len
     * @param int $max_len
     * @return bool|int
     */
    public static function isQq($qq, $min_len = 5, $max_len = 11)
    {
        if (empty($qq)) {
            return false;
        }
        $match = '/^([1-9]\d{' . $min_len . ',' . $max_len . '})$/';
        return preg_match($match, $qq);
    }
}
